home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / winsr173.zip / WINDOS2.C < prev    next >
C/C++ Source or Header  |  1992-07-22  |  33KB  |  1,152 lines

  1.  
  2. /* Windows versions of DOS functions needed by PROMPTS.C */
  3.  
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <dos.h>
  7. #include <sys\types.h>
  8. #include <sys\stat.h>
  9. #include <fcntl.h>
  10. #include <math.h>
  11. #include "fractint.h"
  12. #include "fractype.h"
  13. #include "helpdefs.h"
  14.  
  15. /* routines in this module    */
  16. void movecursor(int row, int col);
  17. void setattr(int row, int col, int attr, int count);
  18. int  putstringcenter(int row, int col, int width, int attr, char far *msg);
  19. void putstring(int row, int col, int attr, unsigned char far *buf);
  20. int  fullscreen_choice(
  21.          int options, char *hdg, char *hdg2, char *instr, int numchoices,
  22.          char **choices, int *attributes, int boxwidth, int boxdepth,
  23.          int colwidth, int current, void (*formatitem)(),
  24.          char *speedstring, int (*speedprompt)(), int (*checkkey)());
  25. int  strncasecmp(char *s,char *t,int ct);
  26. int  input_field(int options, int attr, char *fld, int len, int row, int col, int (*checkkey)(int) );
  27. int  field_prompt(int options, char *hdg, char *instr, char *fld, int len, int (*checkkey)() );
  28. void helptitle(void);
  29. void stackscreen(void);
  30. void unstackscreen(void);
  31. void discardscreen(void);
  32. void load_palette(void);
  33. void save_palette(void);
  34. void fractint_help(void);
  35.  
  36. /* faked/unimplemented routines */
  37.  
  38. void stopslideshow() {}
  39. void aspectratio_crop() {}
  40. void setvideotext() {}
  41. void vidmode_keyname() {}
  42. void load_fractint_cfg() {}
  43. void check_vidmode_key() {}
  44.  
  45. struct videoinfo far *vidtbl;
  46. int vidtbllen = 0;
  47. int badconfig = 0;
  48.  
  49. int win_release = 1730;
  50. char far win_comment[] =
  51. /*   {" "};                /*  publicly-released version */
  52. /*   {"Test Version - Not for Release"};   /* interim test versions */
  53.      {"'Public Beta' Release"};   /* interim test versions */
  54.  
  55. extern int time_to_resume;         /* time to resume? */
  56.  
  57. int text_type = 0;
  58. int textrow = 0, textcol = 0;
  59. int textrbase = 0, textcbase = 0;
  60. int lookatmouse;
  61.  
  62. /* fullscreen_choice options */
  63. #define CHOICERETURNKEY 1
  64. #define CHOICEMENU    2
  65. #define CHOICEHELP    4
  66.  
  67. char speed_prompt[]="Speed key string";
  68.  
  69. int fullscreen_choice(
  70.     int options,         /* &2 use menu coloring scheme           */
  71.                  /* &4 include F1 for help in instructions */
  72.                  /* &8 add caller's instr after normal set */
  73.     char *hdg,         /* heading info, \n delimited           */
  74.     char *hdg2,         /* column heading or NULL               */
  75.     char *instr,         /* instructions, \n delimited, or NULL    */
  76.     int numchoices,      /* How many choices in list           */
  77.     char **choices,      /* array of choice strings            */
  78.     int *attributes,     /* &3: 0 normal color, 1,3 highlight      */
  79.                  /* &256 marks a dummy entry           */
  80.     int boxwidth,         /* box width, 0 for calc (in items)       */
  81.     int boxdepth,         /* box depth, 0 for calc, 99 for max      */
  82.     int colwidth,         /* data width of a column, 0 for calc     */
  83.     int current,         /* start with this item               */
  84.     void (*formatitem)(),/* routine to display an item or NULL     */
  85.     char *speedstring,   /* returned speed key value, or NULL >[30]*/
  86.     int (*speedprompt)(),/* routine to display prompt or NULL      */
  87.     int (*checkkey)()    /* routine to check keystroke or NULL     */
  88. )
  89.    /* return is: n>=0 for choice n selected,
  90.          -1 for escape
  91.           k for checkkey routine return value k (if not 0 nor -1)
  92.       speedstring[0] != 0 on return if string is present
  93.       */
  94. {
  95. static char far choiceinstr1a[]="Use the cursor keys to highlight your selection";
  96. static char far choiceinstr1b[]="Use the cursor keys or type a value to make a selection";
  97. static char far choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out";
  98. static char far choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help";
  99. static char far choiceinstr2c[]="Press ENTER for highlighted choice, or F1 for help";
  100.  
  101.    int titlelines,titlewidth;
  102.    int reqdrows;
  103.    int topleftrow,topleftcol;
  104.    int topleftchoice;
  105.    int speedrow;  /* speed key prompt */
  106.    int boxitems;  /* boxwidth*boxdepth */
  107.    int curkey,increment,rev_increment;
  108.    int redisplay;
  109.    int i,j,k;
  110.    char *charptr;
  111.    char buf[81];
  112.    int speed_match = 0;
  113.    char curitem[81];
  114.    char *itemptr;
  115.    int ret,savelookatmouse;
  116.  
  117.    savelookatmouse = lookatmouse;
  118.    lookatmouse = 0;
  119.    ret = -1;
  120.    if (speedstring
  121.      && (i = strlen(speedstring)) > 0) { /* preset current to passed string */
  122.       current = 0;
  123.       while (current < numchoices
  124.     && (k = strncasecmp(speedstring,choices[current],i)) > 0)
  125.      ++current;
  126.       if (k < 0 && current > 0)  /* oops - overshot */
  127.      --current;
  128.       if (current >= numchoices) /* bumped end of list */
  129.      current = numchoices - 1;
  130.       }
  131.  
  132.    while (1) {
  133.       if (current >= numchoices)  /* no real choice in the list? */
  134.      goto fs_choice_end;
  135.       if ((attributes[current] & 256) == 0)
  136.      break;
  137.       ++current;          /* scan for a real choice */
  138.       }
  139.  
  140.    titlelines = titlewidth = 0;
  141.    if (hdg) {
  142.       charptr = hdg;          /* count title lines, find widest */
  143.       i = 0;
  144.       titlelines = 1;
  145.       while (*charptr) {
  146.      if (*(charptr++) == '\n') {
  147.         ++titlelines;
  148.         i = -1;
  149.         }
  150.      if (++i > titlewidth)
  151.         titlewidth = i;
  152.      }
  153.       }
  154.  
  155.    if (colwidth == 0)          /* find widest column */
  156.       for (i = 0; i < numchoices; ++i)
  157.      if (strlen(choices[i]) > colwidth)
  158.         colwidth = strlen(choices[i]);
  159.  
  160.    /* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */
  161.    reqdrows = 3;          /* calc rows available */
  162.    if (hdg)
  163.       reqdrows += titlelines + 1;
  164.    if (instr) {           /* count instructions lines */
  165.       charptr = instr;
  166.       ++reqdrows;
  167.       while (*charptr)
  168.      if (*(charptr++) == '\n')
  169.         ++reqdrows;
  170.       if ((options & 8))      /* show std instr too */
  171.      reqdrows += 2;
  172.       }
  173.    else
  174.       reqdrows += 2;          /* standard instructions */
  175.    if (speedstring) ++reqdrows;   /* a row for speedkey prompt */
  176.    if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */
  177.       boxdepth = i;
  178.    if (boxwidth == 0) {       /* pick box width and depth */
  179.       if (numchoices <= i - 2) {  /* single column is 1st choice if we can */
  180.      boxdepth = numchoices;
  181.      boxwidth = 1;
  182.      }
  183.       else {              /* sort-of-wide is 2nd choice */
  184.      boxwidth = 60 / (colwidth + 1);
  185.      if (boxwidth == 0
  186.        || (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) {
  187.         boxwidth = 80 / (colwidth + 1); /* last gasp, full width */
  188.         if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i)
  189.            boxdepth = i;
  190.         }
  191.      }
  192.       }
  193.    if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */
  194.       i = 3;
  195.    j = boxwidth * (colwidth += i) + i;       /* overall width of box */
  196.    if (j < titlewidth+2)
  197.       j = titlewidth + 2;
  198.    if (j > 80)
  199.       j = 80;
  200.    if (j <= 70 && boxwidth == 2) {       /* special case makes menus nicer */
  201.       ++j;
  202.       ++colwidth;
  203.       }
  204.    k = (80 - j) / 2;               /* center the box */
  205.    k -= (90 - j) / 20;
  206.    topleftcol = k + i;               /* column of topleft choice */
  207.    i = (25 - reqdrows - boxdepth) / 2;
  208.    i -= i / 4;                   /* higher is better if lots extra */
  209.    topleftrow = 3 + titlelines + i;       /* row of topleft choice */
  210.  
  211.    /* now set up the overall display */
  212.    helptitle();                /* clear, display title line */
  213.    setattr(1,0,C_PROMPT_BKGRD,24*80);       /* init rest to background */
  214.    for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i)
  215.       setattr(i,k,C_PROMPT_LO,j);       /* draw empty box */
  216.    if (hdg) {
  217.       textcbase = (80 - titlewidth) / 2;   /* set left margin for putstring */
  218.       textcbase -= (90 - titlewidth) / 20; /* put heading into box */
  219.       putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg);
  220.       textcbase = 0;
  221.       }
  222.    if (hdg2)                   /* display 2nd heading */
  223.       putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2);
  224.    i = topleftrow + boxdepth + 1;
  225.    if (instr == NULL || (options & 8)) {   /* display default instructions */
  226.       if (i < 20) ++i;
  227.       if (speedstring) {
  228.      speedrow = i;
  229.      *speedstring = 0;
  230.      if (++i < 22) ++i;
  231.      }
  232.       putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  233.         (speedstring) ? choiceinstr1b : choiceinstr1a);
  234.       putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  235.         (options&CHOICEMENU) ? choiceinstr2c
  236.         : ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a));
  237.       }
  238.    if (instr) {                /* display caller's instructions */
  239.       charptr = instr;
  240.       j = -1;
  241.       while ((buf[++j] = *(charptr++)))
  242.      if (buf[j] == '\n') {
  243.         buf[j] = 0;
  244.         putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  245.         j = -1;
  246.         }
  247.       putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  248.       }
  249.  
  250.    boxitems = boxwidth * boxdepth;
  251.    topleftchoice = 0;               /* pick topleft for init display */
  252.    while (current - topleftchoice >= boxitems
  253.      || (current - topleftchoice > boxitems/2
  254.      && topleftchoice + boxitems < numchoices))
  255.       topleftchoice += boxwidth;
  256.    redisplay = 1;
  257.  
  258.    while (1) { /* main loop */
  259.  
  260.       if (redisplay) {                 /* display the current choices */
  261.      if ((options & CHOICEMENU) == 0) {
  262.         memset(buf,' ',80);
  263.         buf[boxwidth*colwidth] = 0;
  264.         for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i)  /* blank the box */
  265.            putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf);
  266.         }
  267.      for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) {
  268.         /* display the choices */
  269.         if ((k = attributes[j = i+topleftchoice] & 3) == 1)
  270.            k = C_PROMPT_LO;
  271.         else if (k == 3)
  272.            k = C_PROMPT_HI;
  273.         else
  274.            k = C_PROMPT_MED;
  275.         if (formatitem)
  276.            (*formatitem)(j,charptr=buf);
  277.         else
  278.            charptr = choices[j];
  279.         putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  280.               k,charptr);
  281.         }
  282.      /***
  283.      ... format differs for summary/detail, whups, force box width to
  284.      ...  be 72 when detail toggle available?  (2 grey margin each
  285.      ...  side, 1 blue margin each side)
  286.      ***/
  287.      if (topleftchoice > 0 && hdg2 == NULL)
  288.         putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)");
  289.      if (topleftchoice + boxitems < numchoices)
  290.         putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)");
  291.      redisplay = 0;
  292.      }
  293.  
  294.       i = current - topleftchoice;         /* highlight the current choice */
  295.       if (formatitem)
  296.      (*formatitem)(current,itemptr=curitem);
  297.       else
  298.      itemptr = choices[current];
  299.       putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  300.         C_CHOICE_CURRENT,itemptr);
  301.  
  302.       if (speedstring) {             /* show speedstring if any */
  303.      memset(buf,' ',80);
  304.      buf[80] = 0;
  305.      putstring(speedrow,0,C_PROMPT_BKGRD,buf);
  306.      if (*speedstring) {             /* got a speedstring on the go */
  307.         putstring(speedrow,15,C_CHOICE_SP_INSTR," ");
  308.         if (speedprompt)
  309.            j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match);
  310.         else {
  311.            putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt);
  312.            j = strlen(speed_prompt);
  313.            }
  314.         strcpy(buf,speedstring);
  315.         i = strlen(buf);
  316.         while (i < 30)
  317.            buf[i++] = ' ';
  318.         buf[i] = 0;
  319.         putstring(speedrow,16+j,C_CHOICE_SP_INSTR," ");
  320.         putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf);
  321.         movecursor(speedrow,17+j+strlen(speedstring));
  322.         }
  323.      else
  324.         movecursor(25,80);
  325.      }
  326.       else
  327.      movecursor(25,80);
  328.  
  329. /*    while (!keypressed()) { } /* enables help */
  330. /*      curkey = getakey(); */
  331.       curkey = keycursor(-2,-2);
  332.  
  333.       i = current - topleftchoice;         /* unhighlight current choice */
  334.       if ((k = attributes[current] & 3) == 1)
  335.      k = C_PROMPT_LO;
  336.       else if (k == 3)
  337.      k = C_PROMPT_HI;
  338.       else
  339.      k = C_PROMPT_MED;
  340.       putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  341.         k,itemptr);
  342.  
  343.       increment = 0;
  344.       switch (curkey) {              /* deal with input key */
  345.      case ENTER:
  346.      case ENTER_2:
  347.         ret = current;
  348.         goto fs_choice_end;
  349.      case ESC:
  350.         goto fs_choice_end;
  351.      case DOWN_ARROW:
  352.      case DOWN_ARROW_2:
  353.         rev_increment = 0 - (increment = boxwidth);
  354.         break;
  355.      case UP_ARROW:
  356.      case UP_ARROW_2:
  357.         increment = 0 - (rev_increment = boxwidth);
  358.         break;
  359.      case RIGHT_ARROW:
  360.      case RIGHT_ARROW_2:
  361.         if (boxwidth == 1) break;
  362.         increment = 1; rev_increment = -1;
  363.         break;
  364.      case LEFT_ARROW:
  365.      case LEFT_ARROW_2:
  366.         if (boxwidth == 1) break;
  367.         increment = -1; rev_increment = 1;
  368.         break;
  369.      case PAGE_UP:
  370.         if (numchoices > boxitems) {
  371.            topleftchoice -= boxitems;
  372.            increment = -boxitems;
  373.            rev_increment = boxwidth;
  374.            redisplay = 1;
  375.            }
  376.         break;
  377.      case PAGE_DOWN:
  378.         if (numchoices > boxitems) {
  379.            topleftchoice += boxitems;
  380.            increment = boxitems;
  381.            rev_increment = -boxwidth;
  382.            redisplay = 1;
  383.            }
  384.         break;
  385.      case CTL_HOME:
  386.         current = -1;
  387.         increment = rev_increment = 1;
  388.         break;
  389.      case CTL_END:
  390.         current = numchoices;
  391.         increment = rev_increment = -1;
  392.         break;
  393.      default:
  394.         if (checkkey) {
  395.            if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0)
  396.           goto fs_choice_end;
  397.            if (ret == -1)
  398.           redisplay = -1;
  399.            }
  400.         ret = -1;
  401.         if (speedstring) {
  402.            i = strlen(speedstring);
  403.            if (curkey == 8 && i > 0) /* backspace */
  404.           speedstring[--i] = 0;
  405.            if (33 <= curkey && curkey <= 126 && i < 30) {
  406.           curkey = tolower(curkey);
  407.           speedstring[i] = curkey;
  408.           speedstring[++i] = 0;
  409.           }
  410.            if (i > 0) {         /* locate matching type */
  411.           current = 0;
  412.           while (current < numchoices
  413.             && (speed_match = strncasecmp(speedstring,choices[current],i)) > 0)
  414.              ++current;
  415.           if (speed_match < 0 && current > 0)  /* oops - overshot */
  416.              --current;
  417.           if (current >= numchoices) /* bumped end of list */
  418.              current = numchoices - 1;
  419.           }
  420.            }
  421.         break;
  422.      }
  423.  
  424.       if (increment) {            /* apply cursor movement */
  425.      current += increment;
  426.      if (speedstring)        /* zap speedstring */
  427.         speedstring[0] = 0;
  428.      }
  429.       while (1) {            /* adjust to a non-comment choice */
  430.      if (current < 0 || current >= numchoices)
  431.          increment = rev_increment;
  432.      else if ((attributes[current] & 256) == 0)
  433.          break;
  434.      current += increment;
  435.      }
  436.       if (topleftchoice > numchoices - boxitems)
  437.      topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems;
  438.       if (topleftchoice < 0)
  439.      topleftchoice = 0;
  440.       while (current < topleftchoice) {
  441.      topleftchoice -= boxwidth;
  442.      redisplay = 1;
  443.      }
  444.       while (current >= topleftchoice + boxitems) {
  445.      topleftchoice += boxwidth;
  446.      redisplay = 1;
  447.      }
  448.       }
  449.  
  450. fs_choice_end:
  451.    lookatmouse = savelookatmouse;
  452.    return(ret);
  453.  
  454. }
  455.  
  456. int input_field(
  457.     int options,          /* &1 numeric, &2 integer, &4 double */
  458.     int attr,          /* display attribute */
  459.     char *fld,          /* the field itself */
  460.     int len,          /* field length (declare as 1 larger for \0) */
  461.     int row,          /* display row */
  462.     int col,          /* display column */
  463.     int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  464.     )
  465. {
  466.    char savefld[81];
  467.    char buf[81];
  468.    int insert, started, offset, curkey, display;
  469.    int i, j;
  470.    int ret,savelookatmouse;
  471.    savelookatmouse = lookatmouse;
  472.    lookatmouse = 0;
  473.    ret = -1;
  474.    strcpy(savefld,fld);
  475.    insert = started = offset = 0;
  476.    display = 1;
  477.    while (1) {
  478.       strcpy(buf,fld);
  479.       i = strlen(buf);
  480.       while (i < len)
  481.      buf[i++] = ' ';
  482.       buf[len] = 0;
  483.       if (display) {                    /* display current value */
  484.      putstring(row,col,attr,buf);
  485.      display = 0;
  486.      }
  487.       curkey = keycursor(row+insert,col+offset);  /* get a keystroke */
  488.       switch (curkey) {
  489.      case ENTER:
  490.      case ENTER_2:
  491.         ret = 0;
  492.         goto inpfld_end;
  493.      case ESC:
  494.         goto inpfld_end;
  495.      case RIGHT_ARROW:
  496.      case RIGHT_ARROW_2:
  497.         if (offset < len) ++offset;
  498.         started = 1;
  499.         break;
  500.      case LEFT_ARROW:
  501.      case LEFT_ARROW_2:
  502.         if (offset > 0) --offset;
  503.         started = 1;
  504.         break;
  505.      case HOME:
  506.         offset = 0;
  507.         started = 1;
  508.         break;
  509.      case END:
  510.         offset = strlen(fld);
  511.         started = 1;
  512.         break;
  513.      case 8:
  514.      case 127:                /* backspace */
  515.         if (offset > 0) {
  516.            j = strlen(fld);
  517.            for (i = offset-1; i < j; ++i)
  518.           fld[i] = fld[i+1];
  519.            --offset;
  520.            }
  521.         started = display = 1;
  522.         break;
  523.      case DELETE:                /* delete */
  524.         j = strlen(fld);
  525.         for (i = offset; i < j; ++i)
  526.            fld[i] = fld[i+1];
  527.         started = display = 1;
  528.         break;
  529.      case 1082:                /* insert */
  530.         insert ^= 0x8000;
  531.         started = 1;
  532.         break;
  533.      case F5:
  534.         strcpy(fld,savefld);
  535.         insert = started = offset = 0;
  536.         display = 1;
  537.         break;
  538.      default:
  539.         if (curkey < 32 || curkey >= 127) {
  540.            if (checkkey && (ret = (*checkkey)(curkey)))
  541.           goto inpfld_end;
  542.            break;                     /* non alphanum char */
  543.            }
  544.         if (offset >= len) break;             /* at end of field */
  545.         if (insert && started && strlen(fld) >= len)
  546.            break;                     /* insert & full */
  547.         if ((options & 1)
  548.           && (curkey < '0' || curkey > '9')
  549.           && curkey != '+' && curkey != '-') {
  550.            if ((options & 2))
  551.           break;
  552.            /* allow scientific notation, and specials "e" and "p" */
  553.            if ( ((curkey != 'e' && curkey != 'E') || offset >= 18)
  554.          && ((curkey != 'p' && curkey != 'P') || offset != 0 )
  555.          && curkey != '.')
  556.           break;
  557.            }
  558.         if (started == 0) /* first char is data, zap field */
  559.            fld[0] = 0;
  560.         if (insert) {
  561.            j = strlen(fld);
  562.            while (j >= offset) {
  563.           fld[j+1] = fld[j];
  564.           --j;
  565.           }
  566.            }
  567.         if (offset >= strlen(fld))
  568.            fld[offset+1] = 0;
  569.         fld[offset++] = curkey;
  570.         /* if "e" or "p" in first col make number e or pi */
  571.         if ((options & 3) == 1) { /* floating point */
  572.            double tmpd;
  573.            int specialv;
  574.            char tmpfld[30];
  575.            specialv = 0;
  576.            if (*fld == 'e' || *fld == 'E') {
  577.           tmpd = exp(1.0);
  578.           specialv = 1;
  579.           }
  580.            if (*fld == 'p' || *fld == 'P') {
  581.           tmpd = atan(1.0) * 4;
  582.           specialv = 1;
  583.           }
  584.            if (specialv) {
  585.           if ((options & 4) == 0)
  586.              roundfloatd(&tmpd);
  587.           sprintf(tmpfld,"%.15g",tmpd);
  588.           tmpfld[len-1] = 0; /* safety, field should be long enough */
  589.           strcpy(fld,tmpfld);
  590.           offset = 0;
  591.           }
  592.            }
  593.         started = display = 1;
  594.      }
  595.       }
  596. inpfld_end:
  597.    lookatmouse = savelookatmouse;
  598.    return(ret);
  599. }
  600.  
  601. int field_prompt(
  602.     int options,        /* &1 numeric value, &2 integer */
  603.     char *hdg,        /* heading, \n delimited lines */
  604.     char *instr,        /* additional instructions or NULL */
  605.     char *fld,        /* the field itself */
  606.     int len,        /* field length (declare as 1 larger for \0) */
  607.     int (*checkkey)()   /* routine to check non data keys, or NULL */
  608.     )
  609. {
  610.    char *charptr;
  611.    int boxwidth,titlelines,titlecol,titlerow;
  612.    int promptcol;
  613.    int i,j;
  614.    char buf[81];
  615.    helptitle();               /* clear screen, display title */
  616.    setattr(1,0,C_PROMPT_BKGRD,24*80);      /* init rest to background */
  617.    charptr = hdg;              /* count title lines, find widest */
  618.    i = boxwidth = 0;
  619.    titlelines = 1;
  620.    while (*charptr) {
  621.       if (*(charptr++) == '\n') {
  622.      ++titlelines;
  623.      i = -1;
  624.      }
  625.       if (++i > boxwidth)
  626.      boxwidth = i;
  627.       }
  628.    if (len > boxwidth)
  629.       boxwidth = len;
  630.    i = titlelines + 4;              /* total rows in box */
  631.    titlerow = (25 - i) / 2;          /* top row of it all when centered */
  632.    titlerow -= titlerow / 4;          /* higher is better if lots extra */
  633.    titlecol = (80 - boxwidth) / 2;      /* center the box */
  634.    titlecol -= (90 - boxwidth) / 20;
  635.    promptcol = titlecol - (boxwidth-len)/2;
  636.    j = titlecol;              /* add margin at each side of box */
  637.    if ((i = (82-boxwidth)/4) > 3)
  638.       i = 3;
  639.    j -= i;
  640.    boxwidth += i * 2;
  641.    for (i = -1; i < titlelines+3; ++i)      /* draw empty box */
  642.       setattr(titlerow+i,j,C_PROMPT_LO,boxwidth);
  643.    textcbase = titlecol;          /* set left margin for putstring */
  644.    putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */
  645.    textcbase = 0;
  646.    i = titlerow + titlelines + 4;
  647.    if (instr) {               /* display caller's instructions */
  648.       charptr = instr;
  649.       j = -1;
  650.       while ((buf[++j] = *(charptr++)))
  651.      if (buf[j] == '\n') {
  652.         buf[j] = 0;
  653.         putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  654.         j = -1;
  655.         }
  656.       putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  657.       }
  658.    else                   /* default instructions */
  659.       putstringcenter(i,0,80,C_PROMPT_BKGRD,
  660.           "Press ENTER when finished (or ESCAPE to back out)");
  661.    return(input_field(options,C_PROMPT_INPUT,fld,len,
  662.               titlerow+titlelines+1,promptcol,checkkey));
  663. }
  664.  
  665. void helptitle()
  666. {
  667.    char msg[80],buf[10];
  668.    setclear(); /* clear the screen */
  669. #ifdef WAITE
  670.    sprintf(msg,"Special WINFRACT  Version %d.%01d",win_release/100,
  671.        (win_release%100)/10);
  672. #else
  673.    sprintf(msg,"WINFRACT  Version %d.%01d",win_release/100,
  674.        (win_release%100)/10);
  675. #endif
  676.    if (win_release%10) {
  677.       sprintf(buf,"%01d",win_release%10);
  678.       strcat(msg,buf);
  679.       }
  680. #ifdef WAITE /* realdos.c */
  681.    strcat(msg," for the Waite Group's Fractals for Windows");
  682. #endif /* WAITE - realdos.c */
  683.    putstringcenter(0,0,80,C_TITLE,msg);
  684. #ifdef WAITE
  685.    return;
  686. #endif
  687. /* uncomment next for production executable: */
  688.    putstring(0,2,C_TITLE_DEV,"'Public-Beta' Release"); 
  689.    return;
  690.    putstring(0,2,C_TITLE_DEV,"Development Version"); 
  691. /* replace above by next after creating production release, for release source */
  692. /* putstring(0,3,C_TITLE_DEV, "Customized Version"); */
  693.    putstring(0,53,C_TITLE_DEV,"Not for Public Release");
  694. }
  695.  
  696. static int screenctr=-1;
  697. #define MAXSCREENS 3
  698. static unsigned char far *savescreen[MAXSCREENS];
  699. static int saverc[MAXSCREENS+1];
  700. static FILE *savescf=NULL;
  701. static char scsvfile[]="fractscr.tmp";
  702.  
  703. void stackscreen()
  704. {
  705.    extern unsigned char far wintext_chars[25][80];
  706.    extern unsigned char far wintext_attrs[25][80];
  707.    int savebytes;
  708.    int i;
  709.    unsigned char far *ptr;
  710.    char buf[100];
  711.    saverc[screenctr+1] = textrow*80 + textcol;
  712.    if (++screenctr) { /* already have some stacked */
  713.      static char far msg[]={"stackscreen overflow"};
  714.       if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
  715.      stopmsg(1,msg);
  716.      exit(1);
  717.      }
  718.       savebytes = 25*80;
  719.       if ((ptr = savescreen[i] = farmemalloc((long)(2*savebytes)))) {
  720.      far_memcpy(ptr,wintext_chars,savebytes);
  721.      far_memcpy(ptr+savebytes,wintext_attrs,savebytes);
  722.      }
  723.       else {
  724.         static char far msg[]={"insufficient memory, aborting"};
  725. fileproblem:   stopmsg(1,msg);
  726.            exit(1);
  727.      }
  728.       setclear();
  729.       }
  730.    else
  731.       setfortext();
  732. }
  733.  
  734. void unstackscreen()
  735. {
  736.    extern unsigned char far wintext_chars[25][80];
  737.    extern unsigned char far wintext_attrs[25][80];
  738.    int savebytes;
  739.    unsigned char far *ptr;
  740.    textrow = saverc[screenctr] / 80;
  741.    textcol = saverc[screenctr] % 80;
  742.    if (--screenctr >= 0) { /* unstack */
  743.       savebytes = 25*80;
  744.       if ((ptr = savescreen[screenctr])) {
  745.      far_memcpy(wintext_chars,ptr,savebytes);
  746.      far_memcpy(wintext_attrs,ptr+savebytes,savebytes);
  747.          wintext_paintscreen(0,80,0,25);
  748.      farmemfree(ptr);
  749.      }
  750.       }
  751.    else
  752.       setforgraphics();
  753.    movecursor(-1,-1);
  754. }
  755.  
  756. void discardscreen()
  757. {
  758.    if (--screenctr >= 0) { /* unstack */
  759.       if (savescreen[screenctr])
  760.      farmemfree(savescreen[screenctr]);
  761.       }
  762.    else
  763.       discardgraphics();
  764. }
  765.  
  766. int discardgraphics()
  767. {
  768. }
  769.  
  770. setfortext()
  771. {
  772. wintext_texton();
  773. }
  774.  
  775. setforgraphics()
  776. {
  777. wintext_textoff();
  778. }
  779.  
  780. setclear()
  781. {
  782. extern int far wintext_buffer_init;
  783.  
  784.     wintext_buffer_init = 0;
  785.     wintext_paintscreen(0,80,0,25);
  786. }
  787.  
  788. int putstringcenter(int row, int col, int width, int attr, char far *msg)
  789. {
  790.    char buf[81];
  791.    int i,j,k;
  792.    i = 0;
  793.    while (msg[i]) ++i; /* strlen for a far */
  794.    if (i == 0) return(-1);
  795.    j = (width - i) / 2;
  796.    j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */
  797.    memset(buf,' ',width);
  798.    buf[width] = 0;
  799.    i = 0;
  800.    k = j;
  801.    while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */
  802.    putstring(row,col,attr,buf);
  803.    return j;
  804. }
  805.  
  806. void putstring(int row, int col, int attr, unsigned char far *buf)
  807. {
  808.     extern unsigned char far wintext_chars[25][80];
  809.     extern unsigned char far wintext_attrs[25][80];
  810.     int i, j, k, maxrow, maxcol;
  811.     char xc, xa;
  812.  
  813.     if (row == -1) row = textrow;
  814.     if (col == -1) col = textcol;
  815.  
  816.     j = maxrow = row;
  817.     k = maxcol = col-1;
  818.  
  819.     for (i = 0; (xc = buf[i]) != 0; i++) {
  820.         if (xc == 13 || xc == 10) {
  821.             j++;
  822.             k = -1;
  823.             }
  824.         else {
  825.             if ((++k) + textcbase >= 80) {
  826.                 j++;
  827.                 k = 0;
  828.                 }
  829.             if (j+textrbase >= 25) j = 24-textrbase;
  830.             if (k+textcbase >= 80) k = 79-textcbase;
  831.             if (maxrow < j) maxrow = j;
  832.             if (maxcol < k) maxcol = k;
  833.             xa = (attr & 0x0ff);
  834.             wintext_chars[j+textrbase][k+textcbase] = xc;
  835.             wintext_attrs[j+textrbase][k+textcbase] = xa;
  836.             }
  837.         }
  838.     if (i > 0) {
  839.         textrow = j;
  840.         textcol = k + 1;
  841.         wintext_paintscreen(
  842.             col+textcbase, maxcol+textcbase,
  843.             row+textrbase, maxrow+textrbase);
  844.         }
  845. }
  846.  
  847. void setattr(int row, int col, int attr, int count)
  848. {
  849. extern unsigned char far wintext_attrs[25][80];
  850.     int i, j, k, maxrow, maxcol;
  851.     char xc, xa;
  852.  
  853.     j = maxrow = row;
  854.     k = maxcol = col-1;
  855.  
  856.     xa = (attr & 0x0ff);
  857.     for (i = 0; i < count; i++) {
  858.         if ((++k + textcbase) >= 80) {
  859.             j++;
  860.             k = 0;
  861.             }
  862.         if (j+textrbase >= 25) j = 24-textrbase;
  863.         if (k+textcbase >= 80) k = 79-textcbase;
  864.         if (maxrow < j) maxrow = j;
  865.         if (maxcol < k) maxcol = k;
  866.         wintext_attrs[j+textrbase][k+textcbase] = xa;
  867.         }
  868.     if (count > 0)
  869.         wintext_paintscreen(
  870.             col+textcbase, maxcol+textcbase,
  871.             row+textrbase, maxrow+textrbase);
  872. }
  873.  
  874. void movecursor(int row, int col)
  875. {
  876. int cursor_type;
  877.  
  878.     cursor_type = -1;
  879.     if (row >= 25 || col >= 80) {
  880.         row=1;
  881.         col=1;
  882.         cursor_type = 0;
  883.         }
  884.     if (row >= 0)
  885.         textrow = row;
  886.     if (col >= 0)
  887.         textcol = col;
  888.     wintext_cursor(col, row, -1);
  889. }
  890.  
  891. int keycursor(int row, int col)
  892. {
  893. int i, cursor_style;
  894.  
  895. if (row == -2 && col == -2) 
  896.     return(fractint_getkeypress(1));
  897.  
  898. if (row == -1)
  899.     row = textrow;
  900. if (col == -1)
  901.     col = textcol;
  902.  
  903. cursor_style = 1;
  904. if (row < 0) {
  905.     cursor_style = 2;
  906.     row = row & 0x7fff;
  907.     }
  908.  
  909. i = fractint_getkeypress(0);
  910. if (i == 0)
  911.     wintext_cursor(col, row, cursor_style);
  912. i = fractint_getkeypress(1);
  913. wintext_cursor(col, row, 0);
  914.  
  915. return(i);
  916.  
  917. }
  918.  
  919. /* get a "fractint-style" keystroke, with "help" sensitivity */
  920. int fractint_getkeypress(int option)
  921. {
  922. int i;
  923.  
  924. restart:
  925.     i = wintext_getkeypress(option);
  926.     if (i == 0)
  927.         return(i);
  928.     /* "fractint-i-size" the keystroke */
  929.     if (i != 0 && (i & 255) == 0)  /* function key? */
  930.         i = (i >> 8) + 1000;
  931.     else
  932.         i = (i & 255);
  933.     if (i == F1) {    /* F1  - bring up Windows-style help */
  934.         if (option == 0) wintext_getkeypress(1);
  935.         winfract_help();
  936.         goto restart;
  937.         }
  938.     if (i == (F1+35)) {  /* Control-F1  - bring up Fractint-style help */
  939.         if (option == 0) wintext_getkeypress(1);
  940.         fractint_help();
  941.         goto restart;
  942.         }
  943.  
  944. return(i);
  945.  
  946. }
  947.  
  948. int getakeynohelp() {
  949. return(fractint_getkeypress(1));
  950. }
  951.  
  952. int strncasecmp(char *s,char *t,int ct)
  953. {
  954.    for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++)
  955.       if(*s == '\0')
  956.      return(0);
  957.    return(tolower(*s) - tolower(*t));
  958. }
  959.  
  960. extern char temp1[];
  961. extern    int    colors;
  962. extern unsigned char dacbox[256][3];
  963. extern unsigned char olddacbox[256][3];
  964. extern int colorstate;
  965. extern char    colorfile[];
  966. char mapmask[13] = {"*.map"};
  967.  
  968. void save_palette()
  969. {
  970.    FILE *dacfile;
  971.    int i,oldhelpmode;
  972.    oldhelpmode = helpmode;
  973.    stackscreen();
  974.    temp1[0] = 0;
  975.    helpmode = HELPCOLORMAP;
  976.    i = field_prompt(0,"Name of map file to write",NULL,temp1,60,NULL);
  977.    unstackscreen();
  978.    if (i != -1 && temp1[0]) {
  979.       if (strchr(temp1,'.') == NULL)
  980.      strcat(temp1,".map");
  981.       dacfile = fopen(temp1,"w");
  982.       if (dacfile == NULL)
  983.      buzzer(2);
  984.       else {
  985.      for (i = 0; i < colors; i++)
  986.         fprintf(dacfile, "%3d %3d %3d\n",
  987.             dacbox[i][0] << 2,
  988.             dacbox[i][1] << 2,
  989.             dacbox[i][2] << 2);
  990.      memcpy(olddacbox,dacbox,256*3);
  991.      colorstate = 2;
  992.      strcpy(colorfile,temp1);
  993.      }
  994.       fclose(dacfile);
  995.       }
  996.    helpmode = oldhelpmode;
  997. }
  998.  
  999.  
  1000. void load_palette(void)
  1001. {
  1002.    int i,oldhelpmode;
  1003.    char filename[80];
  1004.    oldhelpmode = helpmode;
  1005.    strcpy(filename,colorfile);
  1006.    stackscreen();
  1007.    helpmode = HELPCOLORMAP;
  1008.    i = getafilename("Select a MAP File",mapmask,filename);
  1009.    unstackscreen();
  1010.    if (i >= 0)
  1011.       if (ValidateLuts(filename) == 0) {
  1012.      memcpy(olddacbox,dacbox,256*3);
  1013.      colorstate = 2;
  1014.      strcpy(colorfile,filename);
  1015.      }
  1016.    helpmode = oldhelpmode;
  1017. }
  1018.  
  1019. void fractint_help()
  1020. {
  1021.    int i,oldhelpmode;
  1022.  
  1023.    oldhelpmode = helpmode;
  1024.    helpmode = HELP_INDEX;
  1025.    help(0);
  1026.    helpmode = oldhelpmode;
  1027. }
  1028.  
  1029. FILE *parmfile;
  1030.  
  1031. int win_make_batch_file()
  1032. {
  1033.    int i,numparms;
  1034.    int gotinfile;
  1035.    char outname[81],buf[256],buf2[128];
  1036.    FILE *infile;
  1037.    char colorspec[14];
  1038.    int maxcolor;
  1039.    char *sptr,*sptr2;
  1040.    extern char CommandFile[];
  1041.    extern char CommandName[];
  1042.    extern char CommandComment1[];
  1043.    extern char CommandComment2[];
  1044.    extern int  colorstate;
  1045.    extern int win_temp1, win_temp2;
  1046.    extern char colorfile[];
  1047.    extern int  mapset;
  1048.    extern char MAP_name[];
  1049.  
  1050. #ifdef WINFRACT
  1051. extern char suffix[4096];
  1052. #else
  1053. extern char dstack[4096];
  1054. #endif
  1055.    extern char boxx[8192];
  1056.    extern char s_cantopen[];
  1057.    extern char s_cantwrite[];
  1058.    extern char s_cantcreate[];
  1059.    extern char s_cantunderstand[];
  1060.    extern char s_cantfind[];
  1061.  
  1062.       if (strchr(CommandFile,'.') == NULL)
  1063.          strcat(CommandFile,".par"); /* default extension .par */
  1064.       if (win_temp2 > 0 && win_temp2 <= 256)
  1065.         maxcolor = win_temp2;
  1066.       strcpy(colorspec,"n");
  1067.       if (win_temp1 == 0) {      /* default colors */
  1068.      }
  1069.       else if (win_temp1 == 2) { /* colors match colorfile */
  1070.      colorspec[0] = '@';
  1071.      sptr = colorfile;
  1072.      }
  1073.       else              /* colors match no .map that we know of */
  1074.      colorspec[0] = 'y';
  1075.       if (colorspec[0] == '@') {
  1076.      if ((sptr2 = strrchr(sptr,'\\'))) sptr = sptr2 + 1;
  1077.      if ((sptr2 = strrchr(sptr,':')))  sptr = sptr2 + 1;
  1078.      strncpy(&colorspec[1],sptr,12);
  1079.      colorspec[13] = 0;
  1080.      }
  1081.  
  1082.       strcpy(outname,CommandFile);
  1083.       gotinfile = 0;
  1084.       if (access(CommandFile,0) == 0) { /* file exists */
  1085.      gotinfile = 1;
  1086.      if (access(CommandFile,6)) {
  1087.         sprintf(buf,s_cantwrite,CommandFile);
  1088.         stopmsg(0,buf);
  1089.         return(0);
  1090.         }
  1091.      i = strlen(outname);
  1092.      while (--i >= 0 && outname[i] != '\\')
  1093.      outname[i] = 0;
  1094.      strcat(outname,"fractint.tmp");
  1095.      infile = fopen(CommandFile,"rt");
  1096.      setvbuf(infile,suffix,_IOFBF,4096); /* improves speed */
  1097.      }
  1098.       if ((parmfile = fopen(outname,"wt")) == NULL) {
  1099.      sprintf(buf,s_cantcreate,outname);
  1100.      stopmsg(0,buf);
  1101.      if (gotinfile) fclose(infile);
  1102.      return(0);
  1103.      }
  1104.  
  1105.       if (gotinfile) {
  1106.      while (file_gets(buf,255,infile) >= 0) {
  1107.         if (strchr(buf,'{')                    /* entry heading? */
  1108.           && sscanf(buf," %40[^ \t({]",buf2)
  1109.           && stricmp(buf2,CommandName) == 0) { /* entry with same name */
  1110.            sprintf(buf2,"File already has an entry named %s\n\
  1111. Continue to replace it, Cancel to back out",CommandName);
  1112.            if (stopmsg(18,buf2) < 0) {        /* cancel */
  1113.           fclose(infile);
  1114.           fclose(parmfile);
  1115.           unlink(outname);
  1116.           return(0);
  1117.           }
  1118.            while (strchr(buf,'}') == NULL
  1119.          && file_gets(buf,255,infile) > 0 ) { } /* skip to end of set */
  1120.            break;
  1121.            }
  1122.         fputs(buf,parmfile);
  1123.         fputc('\n',parmfile);
  1124.         }
  1125.      }
  1126.  
  1127.       fprintf(parmfile,"%-19s{",CommandName);
  1128.       if (CommandComment1[0]) fprintf(parmfile," ; %s",CommandComment1);
  1129.       fputc('\n',parmfile);
  1130.       if (CommandComment2[0])
  1131.      fprintf(parmfile,"                     ; %s\n",CommandComment2);
  1132.       write_batch_parms(parmfile,colorspec,maxcolor); /* write the parameters */
  1133.       fprintf(parmfile,"  }\n\n");
  1134.  
  1135.       if (gotinfile) {    /* copy the rest of the file */
  1136.      while ((i = file_gets(buf,255,infile)) == 0) { } /* skip blanks */
  1137.      while (i >= 0) {
  1138.         fputs(buf,parmfile);
  1139.         fputc('\n',parmfile);
  1140.         i = file_gets(buf,255,infile);
  1141.         }
  1142.      fclose(infile);
  1143.      }
  1144.       fclose(parmfile);
  1145.       if (gotinfile) {    /* replace the original file with the new */
  1146.      unlink(CommandFile);          /* success assumed on these lines       */
  1147.      rename(outname,CommandFile); /* since we checked earlier with access */
  1148.      }
  1149.  
  1150. return(1);
  1151. }
  1152.